package com.linx.web.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linx.common.core.constant.UserConstants;
import com.linx.common.core.domain.R;
import com.linx.common.core.domain.YsyjRetrunVo;
import com.linx.common.core.domain.model.*;
import com.linx.common.core.exception.ServiceException;
import com.linx.common.core.utils.*;
import com.linx.common.encrypt.annotation.ApiEncrypt;
import com.linx.common.encrypt.utils.EncryptUtils;
import com.linx.common.json.utils.JsonUtils;
import com.linx.common.satoken.utils.LoginHelper;
import com.linx.common.social.config.properties.SocialLoginConfigProperties;
import com.linx.common.social.config.properties.SocialProperties;
import com.linx.common.social.utils.SocialUtils;
import com.linx.common.sse.dto.SseMessageDto;
import com.linx.common.sse.utils.SseMessageUtils;
import com.linx.common.tenant.helper.TenantHelper;
import com.linx.enterprise.domain.EnterpriseInfo;
import com.linx.enterprise.service.IEnterpriseInfoService;
import com.linx.open.common.constant.OpenConstants;
import com.linx.open.domain.bo.YsyjLogBo;
import com.linx.open.service.IYsyjLogService;
import com.linx.park.domain.bo.ParkInfoBo;
import com.linx.park.domain.vo.ParkInfoVo;
import com.linx.park.service.IParkInfoService;
import com.linx.system.domain.SysDept;
import com.linx.system.domain.SysUser;
import com.linx.system.domain.bo.SysTenantBo;
import com.linx.system.domain.dsfvo.YhsfVo;
import com.linx.system.domain.dsfvo.YsyjEnterpriseInfoVo;
import com.linx.system.domain.dsfvo.YsyjUserVo;
import com.linx.system.domain.vo.SysClientVo;
import com.linx.system.domain.vo.SysTenantVo;
import com.linx.system.domain.vo.SysUserParkVo;
import com.linx.system.service.*;
import com.linx.web.domain.vo.*;
import com.linx.web.service.IAuthStrategy;
import com.linx.web.service.SysLoginService;
import com.linx.web.service.SysRegisterService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 认证
 *
 * @author Lion Li
 */
@Slf4j
@SaIgnore
@RequiredArgsConstructor
@RestController
@RequestMapping("/auth")
public class AuthController {

    private final SocialProperties socialProperties;
    private final SysLoginService loginService;
    private final ISysUserService userService;
    private final SysRegisterService registerService;
    private final ISysConfigService configService;
    private final ISysTenantService tenantService;
    private final ISysSocialService socialUserService;
    private final ISysClientService clientService;
    private final ScheduledExecutorService scheduledExecutorService;
    private final IEnterpriseInfoService ienterpriseInfoService;
    private final ISysDeptService iSysDeptService;
    private final IYsyjLogService ysyjLogService;

    private final ISysUserParkService sysUserParkService;
    private final IParkInfoService parkInfoService;


    @Value("${dsfLogin.ysyj.encodedKey}")
    private String encodedKey;

    @Value("${dsfLogin.ysyj.urlGetUserInfo}")
    private String urlGetUserInfo;

    @Value("${zhyq.tenantId}")
    private String tenantId;

    @Value("${zhyq.parentId}")
    private String parentId;

    @Value("${spring.passwordDefault}")
    private static String passwordDefault;


    /**
     * 登录方法
     *
     * @param body 登录信息
     * @return 结果
     */
    @ApiEncrypt
    @PostMapping("/login")
    public R<LoginVo> login(@RequestBody String body) {
        LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
        ValidatorUtils.validate(loginBody);
        // 授权类型和客户端id
        String clientId = loginBody.getClientId();
        String grantType = loginBody.getGrantType();
        SysClientVo client = clientService.queryByClientId(clientId);
        // 查询不到 client 或 client 内不包含 grantType
        if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
            log.info("客户端id: {} 认证类型：{} 异常!.", clientId, grantType);
            return R.fail(MessageUtils.message("auth.grant.type.error"));
        } else if (!UserConstants.NORMAL.equals(client.getStatus())) {
            return R.fail(MessageUtils.message("auth.grant.type.blocked"));
        }
        // 校验租户
        loginService.checkTenant(loginBody.getTenantId());
        // 登录
        LoginVo loginVo = IAuthStrategy.login(body, client, grantType);

        Long userId = LoginHelper.getUserId();
        scheduledExecutorService.schedule(() -> {
            SseMessageDto dto = new SseMessageDto();
            dto.setMessage("欢迎登录云南建投物流国际供应链智慧园区后台管理系统");
            dto.setUserIds(List.of(userId));
            SseMessageUtils.publishMessage(dto);
        }, 5, TimeUnit.SECONDS);
        return R.ok(loginVo);
    }

    /**
     * 云上营家消息登录鉴权方法
     *
     * @param body 云上营家消息登录鉴权方法
     * @return 结果
     * 原逻辑不变，自己在加两个参数，然后res 请求和结果进行加解密； 就是包一层嘛；
     */
    @PostMapping("/loginAuthenticationXx")
    public R<LoginVo> loginAuthenticationXx(@RequestBody String body) {
        String decryptedString = EncryptUtils.decryptByAes(body, encodedKey);
        DsfLoginBody loginBody = JsonUtils.parseObject(decryptedString, DsfLoginBody.class);
        ValidatorUtils.validate(loginBody);
        // 授权类型和客户端id
        String clientId = loginBody.getClientId();
        String grantType = loginBody.getGrantType();
        SysClientVo client = clientService.queryByClientId(clientId);
        client.setCaptchaEnabled(false);
        // 查询不到 client 或 client 内不包含 grantType
        if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
            log.info("客户端id: {} 认证类型：{} 异常!.", clientId, grantType);
            return R.fail(MessageUtils.message("auth.grant.type.error"));
        } else if (!UserConstants.NORMAL.equals(client.getStatus())) {
            return R.fail(MessageUtils.message("auth.grant.type.blocked"));
        }
        // 校验租户
        loginService.checkTenant(loginBody.getTenantId());
        //重新组装自己的登陆
        PasswordLoginBody loginBodyNew = new PasswordLoginBody();
        BeanUtil.copyProperties(loginBody, loginBodyNew);

        // 登录
        LoginVo loginVo = IAuthStrategy.login(JSON.toJSONString(loginBodyNew), client, grantType);

        Long userId = LoginHelper.getUserId();

        //更新营家用户openid
        if (loginBody.getOpenid() != null && !"".equals(loginBody.getOpenid())) {
            userService.updateUserOpenId(userId, loginBody.getOpenid());
        }

        scheduledExecutorService.schedule(() -> {
            SseMessageDto dto = new SseMessageDto();
            dto.setMessage("欢迎登录云南建投物流国际供应链智慧园区后台管理系统");
            dto.setUserIds(List.of(userId));
            SseMessageUtils.publishMessage(dto);
        }, 5, TimeUnit.SECONDS);
        return R.ok(loginVo);
    }

    /**
     * 云上营家根据token获取用户信息接口，并进行模拟登陆
     *
     * @param access_token 云上营家根据token获取用户信息接口，并进行模拟登陆
     * @return 结果
     */
    @GetMapping("/loginDsfYsyj")
    public R<LoginVo> loginDsf(@RequestParam(required = true, value = "access_token") String access_token) throws IOException {

        Map<String, String> parameters = new HashMap<>();
        parameters.put("access_token", access_token);
        String s = HttpClientUtils.sendGet(urlGetUserInfo, parameters);
        YhsfVo jsonYhsfVo = new YhsfVo();
        try {
            jsonYhsfVo = JsonUtils.parseObject(s, YhsfVo.class);
        } catch (Exception e) {
            throw new ServiceException("解析失败，非正常数据" + s);
        }
     /*   //没有模拟token，jsonYhsfVo自己new 一个放个值,把上面代码注释掉
        YhsfVo jsonYhsfVo = new YhsfVo();
        jsonYhsfVo.setUserName("admin");
        jsonYhsfVo.setTenantId("000000");*/
        //根据租户id和userName 获取用户，然后模拟登陆
        SysUser userInfo = userService.selectUserByYhsf(jsonYhsfVo);
        if (null == userInfo) {
            return R.fail(MessageUtils.message("user.password.not.match"));
        }
        PasswordLoginBody loginBody = new PasswordLoginBody();
        loginBody.setPassword(userInfo.getPassword());
        loginBody.setUsername(userInfo.getUserName());
        loginBody.setTenantId(userInfo.getTenantId());
        loginBody.setClientId("e5cd7e4891bf95d1d19206ce24a7b32e");
        loginBody.setGrantType("password");
        // 授权类型和客户端id
        String clientId = loginBody.getClientId();
        String grantType = loginBody.getGrantType();
        SysClientVo client = clientService.queryByClientId(clientId);
        //不进行验证码验证
        client.setCaptchaEnabled(false);
        //不进行密码校验
        client.setPasswordEnabled(false);
        // 查询不到 client 或 client 内不包含 grantType
        if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
            log.info("客户端id: {} 认证类型：{} 异常!.", clientId, grantType);
            return R.fail(MessageUtils.message("auth.grant.type.error"));
        } else if (!UserConstants.NORMAL.equals(client.getStatus())) {
            return R.fail(MessageUtils.message("auth.grant.type.blocked"));
        }
        // 校验租户
        loginService.checkTenant(loginBody.getTenantId());
        // 登录
        LoginVo loginVo = IAuthStrategy.login(JSON.toJSONString(loginBody), client, grantType);
        Long userId = LoginHelper.getUserId();
        scheduledExecutorService.schedule(() -> {
            SseMessageDto dto = new SseMessageDto();
            dto.setMessage("欢迎登录云南建投物流国际供应链智慧园区后台管理系统");
            dto.setUserIds(List.of(userId));
            SseMessageUtils.publishMessage(dto);
        }, 5, TimeUnit.SECONDS);
        return R.ok(loginVo);
    }

    /**
     * 获取云上营家的用户方法
     *
     * @param List<YsyjUserVo> 获取云上营家的用户方法
     * @return 结果
     */
    @PostMapping("/getYsyjUserInfo")
    public YsyjRetrunVo getYsyjUserInfo(@RequestBody List<YsyjUserVo> ysyjUserVoList) {
        YsyjLogBo bo = new YsyjLogBo();
        try {
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(ysyjUserVoList);
            bo.setContentinfo(jsonString);
        } catch (Exception e) {
            bo.setContentinfo("内容为空或者不存在");
        }
        bo.setYsyjType(OpenConstants.ysyjType_USER);
        ysyjLogService.insertByBo(bo);
        try {
            List<SysDept> deptList = new ArrayList<>();
            List<SysUser> userList = new ArrayList<>();
            //转换用户和部门
            getUserAndDept(ysyjUserVoList, deptList, userList);
            //保存部门
            List<SysDept> sysDepts = saveDept(deptList);
            //保存或者更新用户
            saveOrUpdateUser(userList, sysDepts);
        } catch (Exception e) {
            return YsyjRetrunVo.fail(e.getMessage());
        }
        bo.setIsSuccess(OpenConstants.isSuccess_YES);
        ysyjLogService.updateByBo(bo);
        return YsyjRetrunVo.ok();
    }

    private void saveOrUpdateUser(List<SysUser> userList, List<SysDept> deptList) {
        //如果有账号的进行更新，无账号的进行新增
        List<SysUser> userlistAll = userService.selectUserByTenantId(tenantId);
        List<ParkInfoVo> parkInfoList = parkInfoService.queryList(new ParkInfoBo());
        Set<String> userNames = userlistAll.stream().map(SysUser::getUserName).collect(Collectors.toSet());
        // 根据 userName 字段筛选出不包含在 userNames 中的数据
        List<SysUser> insertUserList = new ArrayList<>();
        List<SysUser> updateUserList = new ArrayList<>();
        for (SysUser user : userList) {
            if (parkInfoList.size() > 0) {
                user.setParkInfoId(parkInfoList.get(0).getParkInfoId() + "");
            }
            if (userNames.contains(user.getUserName())) {
                SysDept sysDept = deptList.stream()
                    .filter(dept -> user.getRemark().equals(dept.getDeptCategory()))
                    .findFirst().get();
                user.setDeptId(sysDept.getDeptId());
                updateUserList.add(user);
            } else {
                SysDept sysDept = deptList.stream()
                    .filter(dept -> user.getRemark().equals(dept.getDeptCategory()))
                    .findFirst().get();
                user.setDeptId(sysDept.getDeptId());
                insertUserList.add(user);
            }
        }
        if (updateUserList.size() > 0) {
            userService.updateUserbyUserNameBatch(updateUserList);
        }
        if (insertUserList.size() > 0) {
            userService.insertUserbyUserNameBatch(insertUserList);
        }
    }

    private List<SysDept> saveDept(List<SysDept> deptList) {
        List<SysDept> sysDeptVos = iSysDeptService.selecDeptAll();
        Set<String> deptCategorySet = sysDeptVos.stream()
            .map(SysDept::getDeptCategory)
            .collect(Collectors.toSet());
        // 根据 deptCategory 字段筛选出不包含在 sysDeptVos 中的数据
        List<SysDept> filteredDeptList = deptList.stream()
            .filter(dept -> !deptCategorySet.contains(dept.getDeptCategory()))
            .peek(dept -> {
                // 为每个部门设置 deptPath
                String deptPath = getDeptPath(deptList, dept.getDeptId());
                dept.setAncestors(deptPath);  // 设置路径
            })
            .collect(Collectors.toList());
        if (filteredDeptList.size() > 0) {
            //获取祖籍列表

            iSysDeptService.insertDeptBatch(filteredDeptList);
            sysDeptVos.addAll(filteredDeptList);
        }
        return sysDeptVos;
    }

    public static String getDeptPath(List<SysDept> deptList, Long deptId) {
        // 用来保存路径的列表
        List<Long> deptIds = new ArrayList<>();
        SysDept targetDept = findDeptById(deptList, deptId);

        if (targetDept != null) {
            // 只在当前部门添加园区ID和企业ID
            deptIds.add(targetDept.getParkInfoId());
            deptIds.add(targetDept.getEnterpriseInfoId());

            // 递归获取上级部门ID（只加入父部门的deptId）
            findParentDepts(deptList, targetDept.getParentId(), deptIds);

            // 拼接所有的ID为逗号分隔的字符串
            return String.join(",", deptIds.stream().map(String::valueOf).toArray(String[]::new));
        }

        return null;  // 如果找不到部门，则返回null
    }

    private static SysDept findDeptById(List<SysDept> deptList, Long deptId) {
        // 遍历查找部门
        for (SysDept dept : deptList) {
            if (dept.getDeptId().equals(deptId)) {
                return dept;
            }
        }
        return null;  // 如果没有找到对应的部门
    }

    private static void findParentDepts(List<SysDept> deptList, Long parentId, List<Long> deptIds) {
        // 查找父部门
        SysDept parentDept = findDeptById(deptList, parentId);
        if (parentDept != null) {
            deptIds.add(parentDept.getDeptId());  // 只添加父部门ID

            // 递归查找父部门的父部门
            findParentDepts(deptList, parentDept.getParentId(), deptIds);
        }
    }


    private void getUserAndDept(List<YsyjUserVo> ysyjUserVoList, List<SysDept> deptList, List<SysUser> userList) {
        for (YsyjUserVo item : ysyjUserVoList) {
            if (StringUtils.isEmpty(item.getLoginName())) {
                throw new ServiceException("缺少必填字段loginName");
            }
            if (item.getLoginName().equals(UserConstants.ADMIN)) {
                continue;
            }
            SysUser user = new SysUser();
            user.setTenantId(tenantId);
            //有个问题，目前不支持多部门
            user.setUserName(item.getLoginName());
            user.setNickName(item.getRealName());
            user.setEmail(item.getEmail());
            user.setPhonenumber(item.getPhone());
            if (null != item.getGender() && 0 == item.getGender()) {
                user.setSex(UserConstants.SEX_NV);
            } else {
                user.setSex(UserConstants.SEX_NAN);
            }
            user.setPassword(BCrypt.hashpw(passwordDefault));
            user.setStatus(item.getIsLocked() + "");
            if (null != item.getIsEnabled() && 0 == item.getIsEnabled()) {
                user.setDelFlag(UserConstants.DEL_FLAG_REMOVED);
            } else {
                user.setDelFlag(UserConstants.DEL_FLAG_NORMAL);
            }
            user.setUserType(UserConstants.YSYJ_USER);
            user.setCreateTime(new Date());
            user.setRemark(item.getUnitCode());
            if (null != item.getEnterpriseId()) {
                user.setEnterpriseInfoId(item.getEnterpriseId().longValue());
            }
            userList.add(user);

            //保存部门
            SysDept dept = new SysDept();
            dept.setDeptName(item.getUnitName());
            dept.setDeptCategory(item.getUnitCode());
            dept.setParentId(Long.parseLong(parentId));
            dept.setTenantId(tenantId);
            dept.setEnterpriseInfoId(Long.valueOf(item.getEnterpriseId()));
            deptList.add(dept);
        }
    }

    /**
     * 获取云上营家的企业方法
     *
     * @param List<YsyjEnterpriseInfoVo> 获取云上营家的企业方法
     * @return 结果
     */
    @PostMapping("/getYsyjEnterpriseInfo")
    public YsyjRetrunVo getYsyjEnterpriseInfo(@RequestBody List<YsyjEnterpriseInfoVo> ysyjEnterpriseVoList) {
        YsyjLogBo bo = new YsyjLogBo();
        try {
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(ysyjEnterpriseVoList);
            bo.setContentinfo(jsonString);
        } catch (Exception e) {
            bo.setContentinfo("内容为空或者不存在");
        }
        bo.setYsyjType(OpenConstants.ysyjType_YQ);
        ysyjLogService.insertByBo(bo);
        try {
            List<EnterpriseInfo> enterpriseInfos = getEnterpriseInfos(ysyjEnterpriseVoList);
            YsyjRetrunVo ysyjRetrunVo = ienterpriseInfoService.getYsyjEnterpriseInfo(enterpriseInfos);
            bo.setIsSuccess(OpenConstants.isSuccess_YES);
            ysyjLogService.updateByBo(bo);
            return ysyjRetrunVo;
        } catch (Exception e) {
            return YsyjRetrunVo.fail(e.getMessage());
        }

    }

    @NotNull
    private List<EnterpriseInfo> getEnterpriseInfos(List<YsyjEnterpriseInfoVo> ysyjEnterpriseVoList) {
        ArrayList<EnterpriseInfo> enterpriseInfos = new ArrayList<>();
        for (YsyjEnterpriseInfoVo info : ysyjEnterpriseVoList) {
            EnterpriseInfo enterpriseInfo = new EnterpriseInfo();
            BeanUtil.copyProperties(info, enterpriseInfo);
            enterpriseInfo.setEnterpriseInfoId(info.getEnterpriseId().longValue());
            enterpriseInfo.setEnterpriseName(info.getEnterpriseName());
            enterpriseInfo.setDelFlag(UserConstants.NORMAL);
            enterpriseInfo.setResponsiblePeople(info.getContactName());
            enterpriseInfo.setTelephone(info.getContactPhone());
            enterpriseInfo.setUscc(info.getUnifiedSocialCode());
            enterpriseInfo.setTenantId(tenantId);
            enterpriseInfos.add(enterpriseInfo);
        }
        return enterpriseInfos;
    }


    /**
     * 第三方登录请求
     *
     * @param source 登录来源
     * @return 结果
     */
    @GetMapping("/binding/{source}")
    public R<String> authBinding(@PathVariable("source") String source,
                                 @RequestParam String tenantId, @RequestParam String domain) {
        SocialLoginConfigProperties obj = socialProperties.getType().get(source);
        if (ObjectUtil.isNull(obj)) {
            return R.fail(source + "平台账号暂不支持");
        }
        AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
        Map<String, String> map = new HashMap<>();
        map.put("tenantId", tenantId);
        map.put("domain", domain);
        map.put("state", AuthStateUtils.createState());
        String authorizeUrl = authRequest.authorize(Base64.encode(JsonUtils.toJsonString(map), StandardCharsets.UTF_8));
        return R.ok("操作成功", authorizeUrl);
    }

    /**
     * 第三方登录回调业务处理 绑定授权
     *
     * @param loginBody 请求体
     * @return 结果
     */
    @PostMapping("/social/callback")
    public R<Void> socialCallback(@RequestBody SocialLoginBody loginBody) {
        // 获取第三方登录信息
        AuthResponse<AuthUser> response = SocialUtils.loginAuth(
            loginBody.getSource(), loginBody.getSocialCode(),
            loginBody.getSocialState(), socialProperties);
        AuthUser authUserData = response.getData();
        // 判断授权响应是否成功
        if (!response.ok()) {
            return R.fail(response.getMsg());
        }
        loginService.socialRegister(authUserData);
        return R.ok();
    }


    /**
     * 取消授权
     *
     * @param socialId socialId
     */
    @DeleteMapping(value = "/unlock/{socialId}")
    public R<Void> unlockSocial(@PathVariable Long socialId) {
        Boolean rows = socialUserService.deleteWithValidById(socialId);
        return rows ? R.ok() : R.fail("取消授权失败");
    }


    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public R<Void> logout() {
        loginService.logout();
        return R.ok("退出成功");
    }

    /**
     * 用户注册
     */
    @ApiEncrypt
    @PostMapping("/register")
    public R<Void> register(@Validated @RequestBody RegisterBody user) {
        if (!configService.selectRegisterEnabled(user.getTenantId())) {
            return R.fail("当前系统没有开启注册功能！");
        }
        registerService.register(user);
        return R.ok();
    }

    /**
     * 登录页面租户下拉框
     *
     * @return 租户列表
     */
    @GetMapping("/tenant/list")
    public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
        // 返回对象
        LoginTenantVo result = new LoginTenantVo();
        boolean enable = TenantHelper.isEnable();
        result.setTenantEnabled(enable);
        // 如果未开启租户这直接返回
        if (!enable) {
            return R.ok(result);
        }

        List<SysTenantVo> tenantList = tenantService.queryList(new SysTenantBo());
        List<TenantListVo> voList = MapstructUtils.convert(tenantList, TenantListVo.class);
        try {
            // 如果只超管返回所有租户
            if (LoginHelper.isSuperAdmin()) {
                result.setVoList(voList);
                return R.ok(result);
            }
        } catch (NotLoginException ignored) {
            ignored.getLocalizedMessage();
            log.info("触发NotLoginException异常,异常信息:{}", ignored.getLocalizedMessage());
        }

        // 获取域名
        String host;
        String referer = request.getHeader("referer");
        if (StringUtils.isNotBlank(referer)) {
            // 这里从referer中取值是为了本地使用hosts添加虚拟域名，方便本地环境调试
            host = referer.split("//")[1].split("/")[0];
        } else {
            host = new URL(request.getRequestURL().toString()).getHost();
        }
        // 根据域名进行筛选
        List<TenantListVo> list = StreamUtils.filter(voList, vo ->
            StringUtils.equals(vo.getDomain(), host));
        result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
        return R.ok(result);
    }

    /**
     * 登录页面租户下拉框
     *
     * @return 租户列表
     */
    @GetMapping("/park/list")
    public R<LoginParkVo> parkList(HttpServletRequest request) throws Exception {
        // 返回对象
        LoginParkVo result = new LoginParkVo();
        boolean enable = TenantHelper.isEnable();
        result.setTenantEnabled(enable);
        // 如果未开启租户这直接返回
        if (!enable) {
            return R.ok(result);
        }
        List<ParkListVo> voList = new ArrayList<>();
        if (LoginHelper.isSuperAdmin()) {
            List<SysUserParkVo> sysUserParkVoList = sysUserParkService.queryList(null);

            //将sysUserParkVos中跟voList字段相同的值copy
            for (SysUserParkVo sysUserParkVo : sysUserParkVoList) {
                ParkListVo parkListVo = new ParkListVo();
                BeanUtils.copyProperties(sysUserParkVo, parkListVo);
                voList.add(parkListVo);
            }
            result.setVoList(voList);
            return R.ok(result);
        } else {
            List<SysUserParkVo> sysUserParkVos =
                sysUserParkService.selectSysUserParkVoListByUserId(LoginHelper.getUserId());
            //将 List<SysUserParkVo>转换成List<ParkListVo>

            //将sysUserParkVos中跟voList字段相同的值copy
            for (SysUserParkVo sysUserParkVo : sysUserParkVos) {
                ParkListVo parkListVo = new ParkListVo();
                BeanUtils.copyProperties(sysUserParkVo, parkListVo);
                voList.add(parkListVo);
            }
            result.setVoList(voList);
        }

        // 获取域名
        String host;
        String referer = request.getHeader("referer");
        if (StringUtils.isNotBlank(referer)) {
            // 这里从referer中取值是为了本地使用hosts添加虚拟域名，方便本地环境调试
            host = referer.split("//")[1].split("/")[0];
        } else {
            host = new URL(request.getRequestURL().toString()).getHost();
        }
        // 根据域名进行筛选
        List<ParkListVo> list = StreamUtils.filter(voList, vo ->
            StringUtils.equals(vo.getDomain(), host));
        result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);


        return R.ok(result);
    }

}
